#include <QAction>
#include <QPainter>
#include <QPen>
#include <QTimer>
#include <QDebug>
#include <math.h>
#include "phasestoolbar.h"
#include "protocol_items.h"
#include "pixmapgenerator.h"

PhaseButton::PhaseButton(const QString &_name, QGraphicsItem *parent, QAction *_doubleClickAction, bool _highlightable)
	: QObject(), QGraphicsItem(parent), name(_name), active(false), highlightable(_highlightable), activeAnimationCounter(0), doubleClickAction(_doubleClickAction), width(50)
{
	if (highlightable) {
		activeAnimationTimer = new QTimer(this);
		connect(activeAnimationTimer, SIGNAL(timeout()), this, SLOT(updateAnimation()));
		activeAnimationTimer->setSingleShot(false);
	} else
		activeAnimationCounter = 9.0;
	
	setCacheMode(DeviceCoordinateCache);
}

QRectF PhaseButton::boundingRect() const
{
	return QRectF(0, 0, width, width);
}

void PhaseButton::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
	QRectF iconRect = boundingRect().adjusted(3, 3, -3, -3);
	QRectF translatedIconRect = painter->combinedTransform().mapRect(iconRect);
	qreal scaleFactor = translatedIconRect.width() / iconRect.width();
	QPixmap iconPixmap = PhasePixmapGenerator::generatePixmap(round(translatedIconRect.height()), name);
	
	painter->setBrush(QColor(220 * (activeAnimationCounter / 10.0), 220 * (activeAnimationCounter / 10.0), 220 * (activeAnimationCounter / 10.0)));
	painter->setPen(Qt::gray);
	painter->drawRect(0.5, 0.5, width - 1, width - 1);
	painter->save();
	painter->resetTransform();
	painter->drawPixmap(iconPixmap.rect().translated(round(3 * scaleFactor), round(3 * scaleFactor)), iconPixmap, iconPixmap.rect());
	painter->restore();
	
	painter->setBrush(QColor(0, 0, 0, 255 * ((10 - activeAnimationCounter) / 15.0)));
	painter->setPen(Qt::gray);
	painter->drawRect(0.5, 0.5, width - 1, width - 1);
}

void PhaseButton::setWidth(double _width)
{
	prepareGeometryChange();
	width = _width;
}

void PhaseButton::setActive(bool _active)
{
	if ((active == _active) || !highlightable)
		return;
	
	active = _active;
	activeAnimationTimer->start(50);
}

void PhaseButton::updateAnimation()
{
	if (!highlightable)
		return;
	
	if (active) {
		if (++activeAnimationCounter >= 10)
			activeAnimationTimer->stop();
	} else {
		if (--activeAnimationCounter <= 0)
			activeAnimationTimer->stop();
	}
	update();
}

void PhaseButton::mousePressEvent(QGraphicsSceneMouseEvent * /*event*/)
{
	emit clicked();
}

void PhaseButton::mouseDoubleClickEvent(QGraphicsSceneMouseEvent */*event*/)
{
	triggerDoubleClickAction();
}

void PhaseButton::triggerDoubleClickAction()
{
	if (doubleClickAction)
		doubleClickAction->trigger();
}

PhasesToolbar::PhasesToolbar(QGraphicsItem *parent)
	: QGraphicsItem(parent), width(100), height(100)
{
	QAction *aUntapAll = new QAction(this);
	connect(aUntapAll, SIGNAL(triggered()), this, SLOT(actUntapAll()));
	QAction *aDrawCard = new QAction(this);
	connect(aDrawCard, SIGNAL(triggered()), this, SLOT(actDrawCard()));
	
	PhaseButton *untapButton = new PhaseButton("untap", this, aUntapAll);
//	untapButton->setShortcut(QKeySequence("F5"));
	PhaseButton *upkeepButton = new PhaseButton("upkeep", this);
	PhaseButton *drawButton = new PhaseButton("draw", this, aDrawCard);
//	drawButton->setShortcut(QKeySequence("F6"));
	PhaseButton *main1Button = new PhaseButton("main1", this);
//	main1Button->setShortcut(QKeySequence("F7"));
	PhaseButton *combatStartButton = new PhaseButton("combat_start", this);
//	combatStartButton->setShortcut(QKeySequence("F8"));
	PhaseButton *combatAttackersButton = new PhaseButton("combat_attackers", this);
	PhaseButton *combatBlockersButton = new PhaseButton("combat_blockers", this);
	PhaseButton *combatDamageButton = new PhaseButton("combat_damage", this);
	PhaseButton *combatEndButton = new PhaseButton("combat_end", this);
	PhaseButton *main2Button = new PhaseButton("main2", this);
//	main2Button->setShortcut(QKeySequence("F9"));
	PhaseButton *cleanupButton = new PhaseButton("cleanup", this);
//	cleanupButton->setShortcut(QKeySequence("F10"));
	
	buttonList << untapButton << upkeepButton << drawButton << main1Button << combatStartButton
		<< combatAttackersButton << combatBlockersButton << combatDamageButton << combatEndButton
		<< main2Button << cleanupButton;
	
	for (int i = 0; i < buttonList.size(); ++i)
		connect(buttonList[i], SIGNAL(clicked()), this, SLOT(phaseButtonClicked()));
	
	nextTurnButton = new PhaseButton("nextturn", this, 0, false);
	connect(nextTurnButton, SIGNAL(clicked()), this, SLOT(actNextTurn()));
	
	rearrangeButtons();
	
	retranslateUi();
}

QRectF PhasesToolbar::boundingRect() const
{
	return QRectF(0, 0, width, height);
}

void PhasesToolbar::retranslateUi()
{
	for (int i = 0; i < buttonList.size(); ++i)
		buttonList[i]->setToolTip(getLongPhaseName(i));
}

QString PhasesToolbar::getLongPhaseName(int phase) const
{
	switch (phase) {
		case 0: return tr("Untap step");
		case 1: return tr("Upkeep step");
		case 2: return tr("Draw step");
		case 3: return tr("First main phase");
		case 4: return tr("Beginning of combat step");
		case 5: return tr("Declare attackers step");
		case 6: return tr("Declare blockers step");
		case 7: return tr("Combat damage step");
		case 8: return tr("End of combat step");
		case 9: return tr("Second main phase");
		case 10: return tr("End of turn step");
		default: return QString();
	}
}

void PhasesToolbar::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
	painter->fillRect(boundingRect(), QColor(50, 50, 50));
}

void PhasesToolbar::rearrangeButtons()
{
	for (int i = 0; i < buttonList.size(); ++i)
		buttonList[i]->setWidth(symbolSize);
	nextTurnButton->setWidth(symbolSize);
	
	double y = margin;
	buttonList[0]->setPos(margin, y);
	buttonList[1]->setPos(margin, y += symbolSize);
	buttonList[2]->setPos(margin, y += symbolSize);
	y += ySpacing;
	buttonList[3]->setPos(margin, y += symbolSize);
	y += ySpacing;
	buttonList[4]->setPos(margin, y += symbolSize);
	buttonList[5]->setPos(margin, y += symbolSize);
	buttonList[6]->setPos(margin, y += symbolSize);
	buttonList[7]->setPos(margin, y += symbolSize);
	buttonList[8]->setPos(margin, y += symbolSize);
	y += ySpacing;
	buttonList[9]->setPos(margin, y += symbolSize);
	y += ySpacing;
	buttonList[10]->setPos(margin, y += symbolSize);
	y += ySpacing;
	y += ySpacing;
	nextTurnButton->setPos(margin, y += symbolSize);
}

void PhasesToolbar::setHeight(double _height)
{
	prepareGeometryChange();
	
	height = _height;
	ySpacing = (height - 2 * margin) / (buttonCount * 5 + spaceCount);
	symbolSize = ySpacing * 5;
	width = symbolSize + 2 * margin;
	
	rearrangeButtons();
}

void PhasesToolbar::setActivePhase(int phase)
{
	if (phase >= buttonList.size())
		return;
	
	for (int i = 0; i < buttonList.size(); ++i)
		buttonList[i]->setActive(i == phase);
}

void PhasesToolbar::phaseButtonClicked()
{
	PhaseButton *button = qobject_cast<PhaseButton *>(sender());
	if (button->getActive())
		button->triggerDoubleClickAction();
	emit sendGameCommand(new Command_SetActivePhase(-1, buttonList.indexOf(button)), -1);
}

void PhasesToolbar::actNextTurn()
{
	emit sendGameCommand(new Command_NextTurn, -1);
}

void PhasesToolbar::actUntapAll()
{
	emit sendGameCommand(new Command_SetCardAttr(-1, "table", -1, "tapped", "0"), -1);
}

void PhasesToolbar::actDrawCard()
{
	emit sendGameCommand(new Command_DrawCards(-1, 1), -1);
}
